<template>
  <el-form label-width="90px" label-position="left">
    <el-collapse v-model="activeName">
      <el-collapse-item name="animate" title="动画">
        <div class="collapse-content">
          <el-form-item label="时长" v-if="!isLine">
            <span>{{ activeDuration }}</span>
          </el-form-item>
          <el-form-item label="动画效果" v-if="isLine">
            <el-select popper-class="editor-container-scss"  v-model="store.currentPen.lineAnimateType" placeholder="水流"
              @change="handleChangePen('lineAnimateType')">
              <el-option v-for="item in lineAnimateTypeOptions" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="动画线条" v-show="isLine && Number(store.currentPen.lineAnimateType) === 1">
            <el-select popper-class="editor-container-scss"  ref="lineTypeSelect" v-model="(store.currentPen as CustomPen).customAnimateLineDash" placeholder=""
              @change="handleChangePenLineType">
              <el-option v-for="item in lineStrokeOptions" :key="item.value"  :label="item.label" :value="item.value">
                <img width="75" :src="item.svg" alt="" />
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="圆点大小" v-show="isLine && Number(store.currentPen.lineAnimateType) === 2">
            <el-input-number controls-position="right" v-model="store.currentPen.animateDotSize" :min="6" :step="1"
              placeholder="最小值6" @input="handleChangePen('animateDotSize')"></el-input-number>
          </el-form-item>
          <el-form-item v-for="meta in isLine ? lineFormMeta : shapeFormMeta" :key="meta.key" :label="meta.label">
            <el-select popper-class="editor-container-scss"  v-if="meta.type === 'select'" v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)" :placeholder="meta.placeholder">
              <el-option v-for="item in meta.options" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
            <el-input v-else-if="meta.type === 'input'" v-model="store.currentPen[meta.key]"
              @input="handleChangePen(meta.key)" :placeholder="meta.placeholder"></el-input>
            <el-input-number v-else-if="meta.type === 'input-number'" controls-position="right"
              v-model="store.currentPen[meta.key]" :min="meta.min" :max="meta.max" :step="meta.step"
              :placeholder="meta.placeholder" @input="handleChangePen(meta.key)"></el-input-number>
            <el-color-picker show-alpha :predefine="ColorPredefine" v-else-if="meta.type === 'color-picker'"
              v-model="store.currentPen[meta.key]" @change="handleChangePen(meta.key)"></el-color-picker>
            <el-slider v-else-if="meta.type === 'slider'" v-model="store.currentPen[meta.key]" :min="meta.min"
              :max="meta.max" size="small" />
            <el-switch v-else-if="meta.type === 'switch'" v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)"></el-switch>

            <div v-if="store.currentPen['animateType'] === 'custom'">
              <el-link :underline="false" type="primary" @click="customAnimate">编辑动画</el-link>
            </div>
          </el-form-item>

          <el-form-item v-for="meta in commonFormMeta" :key="meta.key" :label="meta.label">
            <el-select popper-class="editor-container-scss"  v-if="meta.type === 'select'" v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)" :placeholder="meta.placeholder">
              <el-option v-for="item in meta.options" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
            <el-input v-else-if="meta.type === 'input'" v-model="store.currentPen[meta.key]"
              @input="handleChangePen(meta.key)" :placeholder="meta.placeholder"></el-input>
            <el-input-number v-else-if="meta.type === 'input-number'" controls-position="right"
              v-model="store.currentPen[meta.key]" :min="meta.min" :max="meta.max" :step="meta.step"
              :placeholder="meta.placeholder" @input="handleChangePen(meta.key)"></el-input-number>
            <el-color-picker show-alpha :predefine="ColorPredefine" v-else-if="meta.type === 'color-picker'"
              v-model="store.currentPen[meta.key]" @change="handleChangePen(meta.key)"></el-color-picker>
            <el-slider v-else-if="meta.type === 'slider'" v-model="store.currentPen[meta.key]" :min="meta.min"
              :max="meta.max" size="small" />
            <el-switch v-else-if="meta.type === 'switch'" v-model="store.currentPen[meta.key]"
              @change="handleChangePen(meta.key)"></el-switch>
          </el-form-item>
          <el-button type="primary" size="small" :icon="VideoPlay" @click="startAnimate">播放</el-button>
          <el-button type="primary" size="small" :icon="VideoPause" @click="pauseAnimate">暂停</el-button>
          <el-button type="primary" size="small" :icon="CircleClose" @click="stopAnimate">停止</el-button>
        </div>
      </el-collapse-item>
    </el-collapse>

    <EditorCustomAnimate ref="EditorCustomAnimateRef" @confirm="confirmAddCustomAnimate" />
  </el-form>
</template>

<script setup lang="ts">
import { useTopologyEditorStore } from '@/store/modules/topology-editor'
import { ColorPredefine, PenType } from '@/components/TopologyEditor/constant'
import EditorCustomAnimate from "./EditorCustomAnimate.vue"
import type { Option } from 'element-plus/es/components/select-v2/src/select.types'
import type { Pen } from '@meta2d/core'
import type { FormMetaItem } from 'types/editor'
import { VideoPlay, VideoPause, CircleClose} from '@element-plus/icons-vue'
const store = useTopologyEditorStore()
const lineDashedSmall = new URL('../assets/svg/line-dashed-small.svg', import.meta.url).href
const lineDashedLarge = new URL('../assets/svg/line-dashed-large.svg', import.meta.url).href
const lineDashedDot = new URL('../assets/svg/line-dashed-dot.svg', import.meta.url).href
declare const window: any
declare interface CustomPen extends Pen {
  customAnimateLineDash: string
}

defineOptions({
  name: 'EditorPropsPenAnimate'
})

const EditorCustomAnimateRef = ref()
const activeName = ref(['animate', 'tooltips'])
const activeDuration = ref()
const isLine = computed(() => {
  return store.currentPen.type === PenType.Line
})
const lineAnimateTypeOptions: Option[] = [
  { value: 0, label: '水流' },
  { value: 1, label: '水珠流动' },
  { value: 2, label: '圆点' },
  { value: 3, label: '箭头' },
  { value: 4, label: '水滴' }
]
const lineStrokeOptions: Option[] = [
  { value: '5, 5', label: '- - - - - -', svg: lineDashedSmall },
  { value: '10, 10', label: '— — —', svg: lineDashedLarge },
  { value: '10, 10, 2, 10', label: '— · — · —', svg: lineDashedDot }
]
const lineFormMeta = reactive<FormMetaItem[]>([
  {
    type: 'input-number',
    label: '动画线宽',
    key: 'animateLineWidth',
    min: 1,
    step: 1,
    placeholder: '1'
  },
  { type: 'color-picker', label: '动画颜色', key: 'animateColor' },
  {
    type: 'slider',
    label: '动画速度',
    key: 'animateSpan',
    min: 1,
    max: 5
  },
  { type: 'switch', label: '反向流动', key: 'animateReverse' }
])
const shapeFormMeta = reactive<FormMetaItem[]>([
  {
    type: 'select',
    label: '动画效果',
    key: 'animateType',
    options: [
      { value: '', label: '无' },
      { value: 'upDown', label: '上下跳动' },
      { value: 'leftRight', label: '左右跳动' },
      { value: 'heart', label: '心跳' },
      { value: 'success', label: '成功' },
      { value: 'warning', label: '警告' },
      { value: 'error', label: '错误' },
      { value: 'show', label: '炫耀' },
      { value: 'rotate', label: '旋转' },
      { value: 'custom', label: '自定义' }
    ]
  }
])
const commonFormMeta = reactive<FormMetaItem[]>([
  {
    type: 'input-number',
    label: '循环次数',
    key: 'animateCycle',
    min: 1,
    max: Infinity,
    step: 1,
    placeholder: '默认无限循环'
  },
  { type: 'input', label: '下个动画', key: 'nextAnimate', placeholder: 'ID/tag' },
  { type: 'switch', label: '自动播放', key: 'autoPlay' },
  { type: 'switch', label: '保持动画状态', key: 'keepAnimateState' },
  {
    type: 'select',
    label: '线性播放',
    key: 'linear',
    options: [
      { value: true, label: '是' },
      { value: false, label: '否' }
    ]
  }
])

//动画
const frames = {
  'upDown': [
    { y: -10, duration: 100 }, { y: 10, duration: 80 },
    { y: -10, duration: 50 }, { y: 10, duration: 30 }, { y: 0, duration: 300 }
  ],
  'leftRight': [
    { x: -10, duration: 100 }, { x: 10, duration: 80 }, { x: -10, duration: 50 }, { x: 10, duration: 30 }, { x: 0, duration: 300 }
  ],
  'heart': [
    { scale: 1.1, duration: 100 },
    { scale: 1, duration: 400 }
  ],
  'success': [
    { background: '#389e0d22', color: '#237804', duration: 500 }
  ],
  'warning': [
    { color: '#fa8c16', lineDash: [10, 10], duration: 300 },
    { color: '#fa8c16', lineDash: undefined, duration: 500 },
    { color: '#fa8c16', lineDash: [10, 10], duration: 300 }
  ],
  'error': [
    { color: '#cf1322', background: '#cf132222', duration: 100 }
  ],
  'show': [
    { color: '#fa541c', rotate: -10, duration: 100 },
    { color: '#fa541c', rotate: 10, duration: 100 },
    { color: '#fa541c', rotate: 0, duration: 100 }
  ],
  'rotate': [
    { rotate: 360, duration: 1000 }
  ],
  'customErro': [
    { scale: 1.3, color: '#cf1322', duration: 100 },
    { scale: 0.9, color: '#cf1322', duration: 100 }
  ],
}

function handleChangePen(propKey: keyof Pen) {
  const propValue = store.currentPen[propKey]
  console.log('set ' + propKey + ' : ' + propValue)
  let obj = {
    id: store.currentPen.id,
    [propKey]: propValue
  }
  if (propKey === 'animateType') {
    obj.showDuration = getDuration(propValue)
    if (propValue === '') {
      obj.frames = null
    } else {
      obj.frames = frames[propValue]
    }
    activeDuration.value = obj.showDuration
  }
  window.meta2d && window.meta2d.canvas && window.meta2d.setValue(obj, { history: true })
  window.meta2d && window.meta2d.canvas && window.meta2d.render()
}
const lineTypeSelect = ref<ComponentPublicInstance | null>(null)
function handleChangePenLineType(val: string) {
  console.log('set pen lineType', val)
  const strokeType = lineStrokeOptions.find((option) => {
    return option.value === val
  })
  lineTypeSelect.value?.$el.children[0].children[0].setAttribute(
    'style',
    `background: url(${strokeType?.svg}) no-repeat;
            background-size: 80%;
            background-position: center;
          `
  )
  window.meta2d &&
    window.meta2d.setValue({ id: store.currentPen.id, animateLineDash: val.split(',') }, { history: true })
}
function startAnimate() {
  window.meta2d && window.meta2d.canvas && window.meta2d.startAnimate(store.currentPen.id)
}
function pauseAnimate() {
  window.meta2d && window.meta2d.canvas && window.meta2d.pauseAnimate(store.currentPen.id)
}
function stopAnimate() {
  window.meta2d && window.meta2d.canvas && window.meta2d.stopAnimate(store.currentPen.id)
}
function getDuration(value: string) {
  if (value === '') {
    return 0
  } else if (value === 'error') {
    return 100
  } else if (value === 'show') {
    return 300
  } else if (value === 'heart' || value === 'success') {
    return 500
  } else if (value === 'upDown' || value === 'leftRight') {
    return 560
  } else if (value === 'rotate') {
    return 1000
  } else if (value === 'warning') {
    return 1100
  }
}

//自定义动画
function customAnimate() {
  console.log(store.currentPen);
  EditorCustomAnimateRef.value?.show(store.currentPen.frames ?? [])
}

//添加自定义动画
function confirmAddCustomAnimate(data) {
  let obj = {
    id: store.currentPen.id,
    animateType: 'custom',
    frames: data
  }
  window.meta2d && window.meta2d.canvas && window.meta2d.setValue(obj, { history: true })
  window.meta2d && window.meta2d.canvas && window.meta2d.render()
}
</script>
